package com.example.lotterysystem.service.activitystatus.impl;

import com.example.lotterysystem.common.errorcode.ServiceErrorCodeConstants;
import com.example.lotterysystem.common.exception.ServiceException;
import com.example.lotterysystem.service.ActivityService;
import com.example.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.example.lotterysystem.service.activitystatus.operator.AbstractActivityOperator;
import com.example.lotterysystem.service.dto.ConvertActivityStatusDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
@Slf4j
public class ActivityStatusManagerImpl implements ActivityStatusManager {

    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();
    @Autowired
    private ActivityService activityService;


    /**
     * 进行回滚
     * @param convertActivityStatusDTO
     */
    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        // 转化状态
        for (AbstractActivityOperator operator: operatorMap.values()) {
            operator.convert(convertActivityStatusDTO);
        }
        // 更新缓存
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    /**
     * 处理活动相关状态转换
     * @param convertActivityStatusDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class) // 涉及多张表的修改，需要保证事务一致性
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        // 扭转活动状态
        if (CollectionUtils.isEmpty(operatorMap)) {
            log.warn("operatorMap 为空！");
            return;
        }
        // 获取所有处理者对象
        Map<String, AbstractActivityOperator> currMap = new HashMap<>(operatorMap);
        Boolean update = false; // 是否需要更新缓存
        // 先处理：奖品、人员
        update = processConvertStatus(convertActivityStatusDTO, currMap, 1);

        // 后处理：活动
        update = processConvertStatus(convertActivityStatusDTO, currMap, 2) || update;
        // 更新缓存
        if (update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }

    /**
     * 扭转状态
     * @param convertActivityStatusDTO
     * @param currMap
     * @param sequence
     * @return
     */
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currMap,
                                         int sequence) {
        Boolean update = false; // 是否进行更新
        // 遍历 currMap(使用迭代器)
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = currMap.entrySet().iterator();
        while (iterator.hasNext()) {
            // 判断是否需要处理
            AbstractActivityOperator operator = iterator.next().getValue();
            if (operator.sequence() != sequence
                    || !operator.needConvert(convertActivityStatusDTO)) {
                continue;
            }
            // 进行处理
            if (!operator.convert(convertActivityStatusDTO)) {
                log.error("{} 状态转化失败!", operator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }

            // 处理完成，删除当前 operator
            iterator.remove();
            update = true;
        }
        // 返回
        return update;
    }
}
